<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use App\Notifications\PasswordResetLink;
use App\Models\AbstractUser;
use App\Models\EmailVerification;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use App\Http\Requests\Auth\ResetPassword\SendLinkRequest;
use App\Http\Requests\Auth\ResetPassword\SmsResetRequest;
use App\Http\Requests\Auth\ResetPassword\EmailResetRequest;


class ResetPasswordController extends Controller
{

    /**
     * 显示邮箱找回页面
     *
     * @return \Illuminate\View\View
     */
    public function showEmailReset()
    {
        return $this->view('auth.reset-password.email');
    }

    /**
     * 显示手机短信找回页面
     *
     * @return \Illuminate\View\View
     */
    public function showSmsReset()
    {
        return $this->view('auth.reset-password.sms');
    }

    /**
     * 发送重置密码链接
     *
     * @param SendLinkRequest $request
     *
     * @return \Illuminate\Http\RedirectResponse
     * @throws \Exception
     */
    public function sendLink(SendLinkRequest $request)
    {
        $token = token();

        // 创建一个记录
        EmailVerification::updateOrCreate([
            'type' => EmailVerification::TYPE_RESET_PASSWORD,
            'email' => $request->user['email'],
        ], [
            'token' => $token
        ]);

        // 发送链接邮件
        $request->user->notify(new PasswordResetLink($token));

        return $this->back()
            ->withSuccess('发送成功');
    }


    /**
     * 验证Token并显示重置密码页面
     *
     * @param $token
     *
     * @return \Illuminate\View\View
     */
    public function showReset($token)
    {
        $verify = $this->getVerificationOrFail($token);

        return $this->view('auth.reset-passwords.reset')
            ->with([
                'email' => $verify['email'],
                'token' => $token
            ]);
    }

    /**
     * 使用邮箱重置密码
     *
     * @param EmailResetRequest $request
     * @param $token
     *
     * @return \Illuminate\Http\RedirectResponse
     * @throws \Exception
     */
    public function emailReset(EmailResetRequest $request, $token)
    {
        $verify = $this->getVerificationOrFail($token);

        $user = User::where('email', $verify['email'])->first();

        // 重置密码
        $this->reset($user, $request->input('password'));

        // 删除数据库记录
        $verify->delete();

        return $this->back()
            ->withSuccess('密码重置成功!');
    }

    /**
     * 使用短信验证码重置密码
     *
     * @param SmsResetRequest $request
     *
     * @return \Illuminate\Http\RedirectResponse
     */
    public function smsReset(SmsResetRequest $request)
    {
        $user = User::where($request->only('mobile'))->first();

        $this->reset($user, $request->input('password'));

        return $this->back()
            ->withSuccess('密码重置成功!');
    }

    /**
     * 获取验证数据
     *
     * @param $token
     *
     * @return EmailVerification
     */
    protected function getVerificationOrFail($token)
    {
        $verify = EmailVerification::where([
            'type' => EmailVerification::TYPE_RESET_PASSWORD,
            'token' => $token
        ])->first();

        if (!$verify || $verify->isExpired()) {

            $response = $this->route('reset-password')
                ->withError('链接不存在或已过期, 请重试!');

            $this->responseException($response);
        }

        return $verify;
    }

    /**
     * 重置密码
     *
     * @param AbstractUser $user
     * @param $password
     *
     * @return bool
     */
    protected function reset(AbstractUser $user, $password)
    {
        return $user->update([
            'password' => Hash::make($password)
        ]);
    }
}
